package org.example.JVM.ASM.UseASM;


import org.example.JVM.ByteCode.Util.ByteCodeUtils;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;

import java.io.IOException;

import static org.objectweb.asm.Opcodes.*;

/**
 * @description:
 * @author: farprt
 * @create: 2022-11-17 19:02
 **/
public class UseAsmImpInterface {

    public static void main(String[] args) throws IOException {
        String implClassName = SayHelloInterface.class.getName() + "Impl";
        ClassWriter classWriter = new ClassWriter(0);
        classWriter.visit(Opcodes.V1_8
                , ACC_PUBLIC
                , implClassName.replace(".", "/")
                , null
                , Type.getInternalName(Object.class)
                , new String[]{Type.getInternalName(SayHelloInterface.class)});

        MethodVisitor methodVisitor = classWriter.visitMethod(ACC_PUBLIC, "sayHello", "()V", null, null);

        methodVisitor.visitFieldInsn(GETSTATIC
                , Type.getInternalName(System.class)
                , "out"
                , Type.getDescriptor(System.out.getClass())
        );
        methodVisitor.visitLdcInsn("hello world!");
        methodVisitor.visitMethodInsn(INVOKEVIRTUAL
                , Type.getInternalName(System.out.getClass())
                , "println"
                , "(Ljava/lang/String;)V"
                , false);
        methodVisitor.visitInsn(RETURN);
        methodVisitor.visitMaxs(2, 1);
        byte[] byteCode = classWriter.toByteArray();
        ByteCodeUtils.saveToFile(implClassName, byteCode);
    }
}